<?php

/**
 * 用户抽像模型 - 模型类
 * 
 * @package    01CMS
 * @subpackage system
 * @author     rolong at vip.qq.com
 * @version    1.0.0
 * @link       http://www.01cms.com
 */

abstract class UserAbstractModel
{
    private $error;
    
    protected $prefix;
    protected $Db;
    
    public $fields;
    public $username = '';
    public $userid = 0;

    function __construct ()
    {
        $this->setUserTypePrefix($this->prefix);
        $this->Db = model('Db');
    }

    abstract protected function setUserTypePrefix ();

    /**
     * 获取错误信息
     * 
     * @return string
     * @access public
     */
    public function getError ()
    {
        return $this->error;
    }

    /**
     * 设置错误信息
     * 
     * @return string
     * @access void
     */
    public function setError ($error)
    {
        $this->error = $error;
    }

    /**
     * 获取用户信息
     * 
     * @param string $where
     * @param string $field
     * @return object
     * @access public
     */
    function getUser ($where = 1, $field = '*')
    {
        return $this->Db->getRow("SELECT {$field} FROM @@__{$this->prefix}user WHERE {$where}");
    }

    /**
     * 通过用户组ID获取用户组信息
     * 
     * @param string $where
     * @param string $field
     * @return object
     * @access public
     */
    function getGroup ($where = 1, $field = '*')
    {
        return $this->Db->getRow("SELECT {$field} FROM @@__{$this->prefix}group WHERE {$where}");
    }

    /**
     * 获取全部用户组信息
     * 
     * @param string $field
     * @return object
     * @access public
     */
    function getGroups ($field = '*')
    {
        return $this->Db->getRows("SELECT {$field} FROM @@__{$this->prefix}group");
    }

    /**
     * 获取全部权限信息
     * 
     * @param string $field
     * @return object
     * @access public
     */
    function getAuths ($field = '*')
    {
        return $this->Db->getRows("SELECT {$field} FROM @@__{$this->prefix}auth ORDER BY ordering ASC");
    }

    /**
     * 添加用户
     * 
     * @return string
     * @access public
     */
    public function addUser ($data)
    {
        $user = $this->getUser("username = '{$data['username']}'", 'id');
        
        if (count($user) > 0)
        {
            $this->setError("用户名 {$data['username']} 已存在，请使用其它用户名");
            return FALSE;
        }
        
        $data['password'] = encrypt($data['password']);
        $data['regTime'] = TIME;
        $data['loginTime'] = TIME;
        $data['loginIp'] = getIp();
        $data['loginNum'] = 0;
        
        return $this->Db->insert($data, '@@__' . $this->prefix . 'user');
    }

    /**
     * 修改用户
     * 
     * @return string
     * @access public
     */
    public function modUser ($data)
    {
        $user = $this->getUser("username = '{$data['username']}' AND id != {$data['id']}", 'id');
        
        if (count($user) > 0)
        {
            $this->setError("用户名 {$data['username']} 已存在，请使用其它用户名");
            return FALSE;
        }
        
        if (! empty($data['password']))
        {
            $data['password'] = encrypt($data['password']);
        }
        
        return $this->Db->update($data, "id = {$data['id']}", '@@__' . $this->prefix . 'user');
    }

    /**
     * 添加管理组
     * 
     * @return string
     * @access public
     */
    public function addGroup ($data)
    {
        $user = $this->getGroup("name = '{$data['name']}'", 'id');
        
        if (count($user) > 0)
        {
            $this->setError("组名 {$data['name']} 已存在，请使用其它用户名");
            return FALSE;
        }
        
        return $this->Db->insert($data, '@@__' . $this->prefix . 'group');
    }

    /**
     * 修改组别
     * 
     * @return string
     * @access public
     */
    public function modGroup ($data)
    {
        $group = $this->getGroup("name = '{$data['name']}' AND id != {$data['id']}", 'id');
        
        if (count($group) > 0)
        {
            $this->setError("组名 {$data['name']} 已存在，请使用其它用户名");
            return FALSE;
        }
        
        return $this->Db->update($data, "id = {$data['id']}", '@@__' . $this->prefix . 'group');
    }

    /**
     * 通过用户组ID获取菜单信息
     * 
     * @return array
     * @access public
     */
    function getMenu ()
    {
        $groupId = $this->fields->groupId;
        
        $menus = $this->Db->getRows("SELECT * FROM @@__{$this->prefix}menu order by ordering asc;", 0, 'array');
        $auths = $this->Db->getRow("SELECT auth FROM @@__{$this->prefix}group WHERE id={$groupId}");
        $data = array();
        $i = 0;
        foreach ($menus as $menu)
        {
            $items = explode("\n", str_replace("\r\n", "\n", $menu['items']));
            $dataItems = array();
            foreach ($items as $item)
            {
                $itemArr = explode('|', $item);
                $item1 = explode(',', $itemArr[0]);
                $item1[1] = strpos($item1[1], 'http://') === FALSE ? BOOT_URL . '/' . $item1[1] : $item1[1];
                
                if ($auths->auth == '**' || $this->checkAuth($auths->auth, $item1[1]))
                {
                    if (isset($itemArr[1]))
                    {
                        $item2 = explode(',', $itemArr[1]);
                        $item2[1] = strpos($item2[1], 'http://') === FALSE ? BOOT_URL . '/' . $item2[1] : $item2[1];
                        if ($auths->auth == '**' || $this->checkAuth($auths->auth, $item2[1]))
                        {
                            $item1 = array($item1[0], $item1[1], $item2[0], $item2[1]);
                        }
                    }
                    $dataItems[] = $item1;
                }
                else
                {
                    continue;
                }
            }
            if (empty($dataItems))
            {
                continue;
            }
            else
            {
                $data[$i]['id'] = $menu['id'];
                $data[$i]['title'] = $menu['title'];
                $data[$i]['items'] = $dataItems;
                $data[$i]['hidden'] = $menu['hidden'] ? 'hidden' : '';
                $i ++;
            }
        }
        return $data;
    }

    /**
     * 登陆
     * 
     * @param array $data
     * @return bool
     * @access public
     */
    public function login ($data)
    {
        $user = $this->getUser("username = '{$data['username']}'");
        
        if (empty($user))
        {
            $this->error = "用户{$data['username']}不存在";
            return FALSE;
        }
        
        if (encrypt($data['password']) != $user->password)
        {
            $this->error = '密码不正确';
            return FALSE;
        }
        
        if (! isset($user->username))
        {
            $this->error = "用户{$data['username']}不存在";
            return FALSE;
        }
        
        $this->fields = $user;
        
        $this->Db->query("UPDATE @@__" . $this->prefix . "user SET loginTime = " . TIME . ",loginIp = '" . getIp() . "',loginNum = loginNum + 1 WHERE id = {$this->fields->id}");
        
        return $this->setLogin();
    }

    private function setLogin ()
    {
        $time = 7200000;
        
        $status1 = Session::putCookie($this->prefix . 'username', $this->fields->username, $time);
        $status2 = Session::putCookie($this->prefix . 'loginTime', TIME, $time);
        $status3 = Session::putCookie($this->prefix . 'check', encrypt($this->fields->username . $this->fields->password), $time);
        
        return $status1 && $status2 && $status3;
    }

    /**
     * 登出
     * 
     * @return void
     * @access public
     */
    public function logout ()
    {
        $status1 = Session::dropCookie($this->prefix . 'username');
        $status2 = Session::dropCookie($this->prefix . 'check');
        $status3 = Session::dropCookie($this->prefix . 'loginTime');
        
        return $status1 && $status2 && $status3;
    }

    /**
     * 检测登陆
     * 
     * @return bool
     * @access public
     */
    public function isLogined ()
    {
        $username = Session::getCookie($this->prefix . 'username');
        
        if (! empty($username))
        {
            $this->fields = $this->getUser("username = '{$username}'");
            
            if (Session::getCookie($this->prefix . 'check') == encrypt($username . $this->fields->password))
            {
                $group = $this->getGroup("id = {$this->fields->groupId}");
                
                $this->fields->group = $group->name;
                $this->fields->auth = $group->auth;
                $this->username = $this->fields->username;
                $this->userid = $this->fields->id;
                
                if (time() - Session::getCookie($this->prefix . 'loginTime') > 180)
                {
                    $this->setLogin();
                }
                
                return TRUE;
            }
        }
        
        return FALSE;
    }

    /**
     * 检测权限
     * 
     * @param string $authStr
     * @param string $uriStr
     * @return bool
     * @access public
     */
    public function checkAuth ($authStr = '', $uriStr = '')
    {
        if (empty($authStr))
        {
            $authStr = $this->fields->auth;
        }
        
        $uriStr = str_replace(BOOT_URL . '/', '', $uriStr);
        $authArr = explode(',', $authStr);
        
        if (in_array('**', $authArr))
        {
            return true;
        }
        
        if (empty($uriStr))
        {
            $uriStr = Base::i()->Uri->getPathInfo();
        
        }
        
        $uriArr = explode('/', $uriStr);
        $authArr = array_filter($authArr, "notEmpty");
        $return = FALSE;
        
        foreach ($authArr as $segmentStr)
        {
            $segmentArr = explode('/', $segmentStr);
            $count = count($segmentArr);
            
            for ($j = 0; $j < $count; $j ++)
            {
                if ($segmentArr[$j] == '*')
                {
                    $return = true;
                    break;
                }
                else if ((! isset($segmentArr[$j])) || (! isset($uriArr[$j])) || (strtolower($segmentArr[$j]) != strtolower($uriArr[$j])))
                {
                    break;
                }
            }
        }
        
        return $return;
    }
    
    function __get($name)
    {
        return isset($this->$name) ? $this->$name : $this->fields->$name;
    }
}
